"""
异常的语法
"""

def upper(str_data):
    new_str = None
    try:
        new_str = str_data.upper()
    except:
        print('程序出错了')
    return new_str

str1 = upper('abc')
print(str1)
str2 = upper(123)
print(str2)

#捕获通用异常
try:
    1/0
except Exception as e:
    print(e) #division by zero
    print(type(e)) #<class 'ZeroDivisionError'>
    print(dir(e))

#捕获具体异常
try:
    1/0
except ZeroDivisionError as e:
    print(e)
except Exception as e: #捕获多个异常，当捕获到第一个ZeroDivisionError后，不会继续往下捕获
    print(f'this is a public except,bug is {e}')
except (ZeroDivisionError, Exception) as e: #或者这样捕获多个异常
    print(e)

#常见异常类型
#Exception 通用异常类型（基类）
#ZeroDivisionError 不能整除0
#AttributeError 对象没有这个属性
#IOError 输入输出操作失败
#IndexError 没有当前的索引
#KeyError 没有这个键值（key）
#NameError 变量名未定义（未初始化对象）
#SyntaxError Python语法错误
#SystemError 解释器的系统错误
#ValueError 传入的参数错误


#finally的功能与用法
#无论是否发生异常，一定会执行的代码块
#在函数中，即便在try或except中进行了return也依然会执行finally语法块
#try语法至少要伴随except或finally中的一个

def test():
    try:
        1/0
    except Exception as e:
        return 1
    finally:
        print('finally')
        return 2 #如果不写最终print(a)显示1
a = test() #finally
print(a) #2

#自定义抛出异常用法：
#raise 异常类型(message) 其中message是错误信息 无返回值
# raise ValueError('主动抛出一个异常')
#可以用try-except捕获异常

try:
    raise Exception('抛出异常')
except Exception as e:
    print(e)


#自定义异常类
#1.继承基类-Exception
#2.在构造函数中定义错误信息

class NewError(Exception):
    def __init__(self, message):
        self.message = message

def test():
    raise NewError('新定义的异常类抛出错误')

try:
    test()
except NewError as e:
    print(e)


"""
断言assert：用于判断一个表达式，在表达式条件为False的时候触发异常
"""

#用法：assert expression,message
#其中expression：表达式，一般是判断相等，或判断某种数据类型的bool判断语句
#message：具体错误信息
#无返回值
#如果表达式为True，则不会抛出异常，顺利执行下一行代码，否则抛出AssertionError

assert 1==1
# assert 1>2 可以不填message参数
# assert 1>2 ,'数字比较错误'
print(isinstance('123',int)) #insinstance判断某个数据的数据类型

#pycharm debug
#恢复程序F9  继续执行程序，直到下一个断点或者程序结束。
#步过F8  执行当前行，如果当前行是一个函数，则不会进入函数内部。
#步入F7  进入函数内部执行，如果当前行不是一个函数调用,则和步过一样
#步出shift+F8 执行完当前函数的剩余部分，并停在调用该函数的地方

